﻿using System;
using System.Windows;
using System.Windows.Media;

namespace Wpf.Windows
{
    /// <summary>
    /// DependencyRoutedWindow.xaml 的交互逻辑
    /// </summary>
    public partial class DependencyRoutedWindow : Window
    {
        public DependencyRoutedWindow()
        {
            InitializeComponent();
            this.ContentRendered += DependencyRoutedWindow_ContentRendered;
            OldColor = ((SolidColorBrush)this.Background).Color;
            this.BgColorChanged += DependencyRoutedWindow_BgColorChanged;
        }

        private void DependencyRoutedWindow_BgColorChanged(object sender, RoutedEventArgs e)
        {
            if(e is BgColorChangedEventArgs)
            {
                MessageBox.Show("背景色改变：" + (e as BgColorChangedEventArgs).NewColor.ToString());
            }
            else
            {
                MessageBox.Show("背景色改变!");
            }
        }

        private Color OldColor { get; set; }

        private void CheckBgColor()
        {
            var ncolor = ((SolidColorBrush)this.Background).Color;
            if (ncolor.ToString() != OldColor.ToString())
            {
                OldColor = ncolor;
                this.RaiseEvent(new BgColorChangedEventArgs(BgColorChangedEvent, this, ncolor));
            }
        }

        private void DependencyRoutedWindow_ContentRendered(object sender, EventArgs e)
        {
            CheckBgColor();
        }

        /*
         依赖性属性
        提供一种方法用于计算根据其他输入得到的属性值
        其他输入：系统属性、实时属性确定机制、重用模版、其他公开值
        路由事件
        冒泡事件：子控件--->父控件
        隧道事件：父控件--->子控件
        自定义路由事件
        1.声明并注册路由事件 
        2.为路由事件添加CLR包装
        3.创建激发事件的方法
         */

        //定义并注册依赖性属性
        public readonly DependencyProperty ColorExProperty = DependencyProperty.Register(
            "ColorEx",
            typeof(string),
            typeof(DependencyRoutedWindow),
            new FrameworkPropertyMetadata(
                null,
                FrameworkPropertyMetadataOptions.AffectsRender,
                new PropertyChangedCallback(OnColorExChanged)
                )
            );

        //定义CLR包装
        public string ColorEx
        {
            get { return (string)GetValue(ColorExProperty); }
            set { SetValue(ColorExProperty, value); }
        }

        //定义并注册路由事件
        private static readonly RoutedEvent BgColorChangedEvent = EventManager.RegisterRoutedEvent(
            "ColorChanged",
            RoutingStrategy.Bubble,
            typeof(EventHandler<BgColorChangedEventArgs>),
            typeof(DependencyRoutedWindow)
            );

        //CLR包装事件
        public event RoutedEventHandler BgColorChanged
        {
            add { this.AddHandler(BgColorChangedEvent, value); }
            remove { this.RemoveHandler(BgColorChangedEvent, value); }
        }

        private static void OnColorExChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }

        private void StackPanel_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(e.Source.ToString() + "\n" + Info.GetCallingMethod());
        }

        private void StackPanel_Click_1(object sender, RoutedEventArgs e)
        {
            e.Handled = true;
            MessageBox.Show(e.Source.ToString() + "\n" + Info.GetCallingMethod());
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(e.Source.ToString() + "\n" + Info.GetCallingMethod());
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            var rx = new Random();
            var color = Color.FromArgb(200, (byte)rx.Next(0, 255), (byte)rx.Next(0, 255), (byte)rx.Next(0, 255));
            this.Background = new SolidColorBrush(color);
        }
    }

    public class BgColorChangedEventArgs : RoutedEventArgs
    {
        public System.Windows.Media.Color NewColor { get; private set; }
        public BgColorChangedEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source)
        {
        }
        public BgColorChangedEventArgs(RoutedEvent routedEvent, object source,System.Windows.Media.Color newColor) : this(routedEvent, source)
        {
            NewColor = newColor;
        }
    }

}